﻿
using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Text;
using MethodWorx.CMS.Content;
using MethodWorx.Core.Extensions;
using System.Data.Linq.Mapping;
using MethodWorx.Core.DomainModel;
using MethodWorx.CMS.Workflow;

namespace MethodWorx.CMS.Linq
{
    [Table(Name="dbo.PageTemplate")]
    public class LinqPageTemplate : PageTemplate, IPersistable
    {
        private EntitySet<LinqPageTemplateConstraint> proxyPageTemplateConstraints;
        private EntitySet<LinqContentTemplateConstraint> proxyContentTemplateConstraints;
        private EntitySet<LinqPageTemplateProperty> proxyProperties;
        private EntityRef<LinqPageTemplate> proxyParent;
        private WorkflowConfiguration[] workflows;

        private PageTemplateBindings bindings = null;

        public LinqPageTemplate()
            : base((pt) => ((LinqPageTemplate)pt).ProxyPageTemplateConstraints.Where(p => p.ProxyRelatedTemplate.Deleted == false),
                   (pt) => ((LinqPageTemplate)pt).ProxyContentTemplateConstraints.Where(p => p.ProxyRelatedTemplate.Deleted == false),
                   (pt) => ((LinqPageTemplate)pt).ProxyProperties)
        {
            this.proxyContentTemplateConstraints = new EntitySet<LinqContentTemplateConstraint>();
            this.proxyPageTemplateConstraints = new EntitySet<LinqPageTemplateConstraint>();
            this.proxyProperties = new EntitySet<LinqPageTemplateProperty>();
            this.proxyParent = new EntityRef<LinqPageTemplate>();
        }

        [Column(IsPrimaryKey=true)]
        public new Guid Id { get { return base.Id; } set { base.Id = value; } }
        [Column(UpdateCheck = UpdateCheck.Never)]
        public new string Name { get { return base.Name; } set { base.Name = value; } }
        [Column(UpdateCheck = UpdateCheck.Never)]
        public new string Description { get { return base.Description; } set { base.Description = value;} }
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new bool AllowedAtRoot { get { return base.AllowedAtRoot; } set { base.AllowedAtRoot = value; } }
        [Column(UpdateCheck=UpdateCheck.Never, Name="Bindings")]
        public string BindingsStorage { get; set; }
        [Column(UpdateCheck = UpdateCheck.Never)]
        public new bool Abstract { get { return base.Abstract; } set { base.Abstract = value; } }
        #region Proxy Property For Deleted
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new bool Deleted { get { return base.Deleted; } set { base.Deleted = value; } }
        #endregion
        
        #region Proxy Property For DatePublished
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new DateTime? DatePublished { get { return base.DatePublished; } set { base.DatePublished = value; } }
        #endregion
      
        
        #region Proxy Property For Script
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new string Script { get { return base.Script; } set { base.Script = value; } }
        #endregion
      
        
        #region Proxy Property For Css
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new string Css { get { return base.Css; } set { base.Css = value; } }
        #endregion
      
      
        
        #region Proxy Property For Template
        [Column(UpdateCheck=UpdateCheck.Never)]
        public new string Template { get { return base.Template; } set { base.Template = value; } }
        #endregion

        public override WorkflowConfiguration[] Workflows
        {
            get
            {
                if (this.workflows == null)
                {
                    this.workflows = (WorkflowConfiguration[])this.WorkflowStorage.Base64DeserializeUsingXml(typeof(BranchStep), typeof(DefaultBranchStep)) ?? new WorkflowConfiguration[] { };
                }
                return this.workflows;
            }
            set
            {
                this.workflows = value;
                this.WorkflowStorage = this.workflows.Base64SerializeUsingXml(typeof(BranchStep), typeof(DefaultBranchStep));
            }
        }

        [Column(UpdateCheck = UpdateCheck.Never, Name = "Workflows")]
        public string WorkflowStorage { get; set; }
        
        public override PageTemplateBindings Bindings
        {
            get
            {
                if(this.bindings == null)
                {
                    this.bindings = (PageTemplateBindings)this.BindingsStorage.Base64DeserializeUsingXml();
                }
                return this.bindings;
            }
            set
            {
                this.bindings = value;
                this.BindingsStorage = this.bindings.Base64SerializeUsingXml();
            }
        }

        [Association(Name="PageTemplateConstraints", OtherKey = "ParentTemplateId", ThisKey="Id", Storage = "proxyPageTemplateConstraints")]
        public EntitySet<LinqPageTemplateConstraint> ProxyPageTemplateConstraints
        {
            get { return this.proxyPageTemplateConstraints;  }
            set { this.proxyPageTemplateConstraints.Assign(value); }
        }

        [Column(UpdateCheck=UpdateCheck.Never, CanBeNull=true)]
        public Guid? ParentId { get; set; }

        [Association(Name = "ContentTemplateConstraints", OtherKey = "ParentTemplateId", ThisKey = "Id", Storage = "proxyContentTemplateConstraints")]
        public EntitySet<LinqContentTemplateConstraint> ProxyContentTemplateConstraints
        {
            get { return this.proxyContentTemplateConstraints; }
            set { this.proxyContentTemplateConstraints.Assign(value); }
        }

        [Association(Name = "PageTemplateProperties", OtherKey = "PageTemplateId", ThisKey = "Id", Storage = "proxyProperties")]
        public EntitySet<LinqPageTemplateProperty> ProxyProperties
        {
            get { return this.proxyProperties; }
            set { this.proxyProperties.Assign(value); }
        }

        [Association(IsForeignKey=true, Name="Parent", OtherKey="Id", ThisKey="ParentId", Storage="proxyParent")]
        public LinqPageTemplate ProxyParent
        {
            get { return this.proxyParent.Entity; }
            set { this.proxyParent.Entity = value; }
        }

        public override PageTemplate Parent
        {
            get
            {
                return this.ProxyParent;
            }
            set
            {
                this.ProxyParent = (LinqPageTemplate)value; 
            }
        }
    }
}
